#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
详细调试排列5预测问题
"""

import sys
import os
import torch
import numpy as np
from PyQt5.QtWidgets import QApplication

# 添加项目根目录到路径
project_root = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, project_root)

def debug_plw_detailed():
    """详细调试排列5预测"""
    print(" 详细调试排列5预测问题")
    print("=" * 60)
    
    try:
        from lottery_predictor_app import LotteryPredictorApp
        from algorithms.plw_sequence_lstm import PLWDataProcessor
        
        # 创建应用
        if not QApplication.instance():
            app = QApplication(sys.argv)
        
        predictor = LotteryPredictorApp()
        
        print("[INFO] 步骤1: 检查模型加载...")
        try:
            plw_model, _, scaler_X = predictor.load_models_with_cache("plw")
            print(f"[INFO] 模型加载成功")
            print(f"   模型类型: {type(plw_model)}")
            print(f"   LSTM输入维度: {plw_model.lstm.input_size}")
            print(f"   LSTM隐藏维度: {plw_model.lstm.hidden_size}")
        except Exception as e:
            print(f"[ERROR] 模型加载失败: {e}")
            return False
        
        print("\n[INFO] 步骤2: 检查数据处理...")
        try:
            plw_data_file = os.path.join(project_root, 'scripts', 'plw', 'plw_history.csv')
            processor = PLWDataProcessor(plw_data_file, window_size=10)
            recent_data = processor.get_recent_data()
            print(f"[INFO] 数据处理成功")
            print(f"   最近数据形状: {recent_data.shape if recent_data is not None else 'None'}")
            if recent_data is not None:
                print(f"   数据示例: {recent_data[0, -1, :5].tolist()}")  # 显示最后时间步的5个数字
        except Exception as e:
            print(f"[ERROR] 数据处理失败: {e}")
            import traceback
            traceback.print_exc()
            return False
        
        print("\n[INFO] 步骤3: 检查预测逻辑...")
        try:
            if recent_data is not None and len(recent_data) > 0:
                # 准备输入数据
                if recent_data.shape[-1] == 10:  # 如果是带区域转换特征的数据
                    input_data = recent_data[:, :, :5]  # 只取前5个数字特征
                else:
                    input_data = recent_data
                
                print(f"   输入数据形状: {input_data.shape}")
                print(f"   输入数据示例: {input_data[0, -1, :].tolist()}")
                
                # 确保输入数据与模型在同一设备上
                device = next(plw_model.parameters()).device
                input_data = input_data.to(device)
                print(f"   设备: {device}")
                
                # 使用模型预测
                plw_model.eval()
                with torch.no_grad():
                    plw_predictions = plw_model(input_data)
                    print(f"   模型输出类型: {type(plw_predictions)}")
                    if isinstance(plw_predictions, torch.Tensor):
                        print(f"   模型输出形状: {plw_predictions.shape}")
                        print(f"   模型输出示例: {plw_predictions[0, -1, :5].tolist()}")
                    elif isinstance(plw_predictions, list):
                        print(f"   模型输出长度: {len(plw_predictions)}")
                        if len(plw_predictions) > 0:
                            print(f"   第一个元素类型: {type(plw_predictions[0])}")
                            if isinstance(plw_predictions[0], torch.Tensor):
                                print(f"   第一个元素形状: {plw_predictions[0].shape}")
                    else:
                        print(f"   模型输出: {plw_predictions}")
                
                # 处理预测结果
                if plw_predictions is not None:
                    if isinstance(plw_predictions, torch.Tensor):
                        if plw_predictions.dim() == 3:  # [batch, seq_len, features]
                            predicted_sequence = plw_predictions[0, -1, :5].cpu().numpy()
                        elif plw_predictions.dim() == 2:  # [batch, features]
                            predicted_sequence = plw_predictions[0, :5].cpu().numpy()
                        else:
                            predicted_sequence = plw_predictions.cpu().numpy()
                    elif isinstance(plw_predictions, list):
                        # 处理列表类型的输出
                        if len(plw_predictions) > 0:
                            first_item = plw_predictions[0]
                            if isinstance(first_item, torch.Tensor):
                                if first_item.dim() == 2:  # [seq_len, features]
                                    predicted_sequence = first_item[-1, :5].cpu().numpy()
                                else:
                                    predicted_sequence = first_item[:5].cpu().numpy()
                            else:
                                predicted_sequence = first_item[:5] if len(first_item) >= 5 else first_item
                        else:
                            predicted_sequence = []
                    else:
                        predicted_sequence = plw_predictions
                    
                    print(f"   预测序列: {predicted_sequence}")
                    print(f"   预测序列类型: {type(predicted_sequence)}")
                    
                    # 确保预测结果在0-9范围内
                    if hasattr(predicted_sequence, '__iter__'):
                        predicted_numbers = [max(0, min(9, int(num))) for num in predicted_sequence[:5]]
                        print(f"   最终预测数字: {predicted_numbers}")
                    else:
                        print(f"   预测结果不是可迭代对象: {predicted_sequence}")
            else:
                print("[ERROR] 无法获取最近数据")
        except Exception as e:
            print(f"[ERROR] 预测逻辑失败: {e}")
            import traceback
            traceback.print_exc()
            return False
        
        print("\n[INFO] 步骤4: 测试完整的预测方法...")
        try:
            predictions = predictor.get_lstm_crf_predictions("plw", 1)
            print(f"[INFO] 完整预测方法执行完成")
            print(f"   预测结果数量: {len(predictions)}")
            for i, pred in enumerate(predictions):
                print(f"   第{i+1}组: {pred}")
        except Exception as e:
            print(f"[ERROR] 完整预测方法失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
        return True
        
    except Exception as e:
        print(f"[ERROR] 调试失败: {e}")
        import traceback
        traceback.print_exc()
        return False

if __name__ == "__main__":
    debug_plw_detailed()